/* UTF8 Encoding */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : Car_ctrl.h
  - Author        : liuzhihua (liuzhihuawy@163.com)
  - Update date   : 2024.07.30
  - Brief         : 
  - Version       : v0.1
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                      Note
  * ------------   ---------------   ----------------------------------
  *  2024.07.29       liuzhihua                  Create file          
***/

#ifndef CAR_CTRL_H
#define CAR_CTRL_H

/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include "Car_port.h"
#include "pid.h"
#ifdef  __cplusplus
    extern "C" {
#endif
/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/
//events
#define CAR_CTRL_FIND_LINE    (1)
#define CAR_CTRL_NO_FIND_LINE (1<<1)
#define CAR_CTRL_TIME_EVENT   (1<<2)
#define CAR_CTRL_ALL_EVENTS   (0xFF)

typedef enum
{
    CAR_CTRL_STATE_IDLE,    // 空闲
    CAR_CTRL_STATE_LINE,    // 直线
    CAR_CTRL_STATE_ROTATE,  // 旋转
    CAR_CTRL_STATE_TRACK,   // 循迹
    CAR_CTRL_STATE_STOP,    // 停止
} Car_ctrl_state_e;

typedef enum
{
    CAR_CTRL_TASK_IDLE,   // 空闲
    CAR_CTRL_AUTO,     // 自动
    CAR_CTRL_TEST,     // 测试
    CAR_CTRL_TASK1,    // 任务1
    CAR_CTRL_TASK2,    // 任务2
    CAR_CTRL_TASK3,    // 任务3
    CAR_CTRL_TASK4,    // 任务4
} Car_ctrl_task_e;

typedef struct
{
	uint16_t data;
	int16_t position;
	int16_t _position; //上次位置
	int8_t errR;
	int8_t errL;
  uint16_t noLineCnt;
  uint16_t LineCnt;
  uint32_t timeNoLineCnt;
  uint32_t timeLineCnt;
  uint32_t timeNoLine;
  uint32_t timeLine;
} Tracker_t;

typedef enum {
    KEYPOINT_TYPE_STOP,   // 停止运动
    KEYPOINT_TYPE_LINE,   // 直线运动
    KEYPOINT_TYPE_ROTATE, // 旋转运动
    KEYPOINT_TYPE_TRACK,  // 跟踪运动
    KEYPOINT_TYPE_ROTATEOPEN // 开环旋转
}KPTYPE_t;

typedef struct {
    KPTYPE_t type; // 类型
    uint8_t event; // 触发事件
    int8_t speed;  // 速度
    int16_t angle; // 角度
	uint16_t time; // 时间
    int distance;  // 距离
}CarKeyPoint_t;


typedef struct 
{
    // PID参数
    pid_inc_t pid_LSpeed;
    pid_inc_t pid_RSpeed;
    pid_inc_t pid_Angle;
    pid_inc_t pid_Track;

    uint8_t speed_fb_flag; // 速度闭环标志
    uint8_t angle_fb_flag; // 角度速度闭环标志
    uint8_t track_fb_flag; // 循迹闭环标志
    uint8_t check_point_flag; // 检测点标志

    // 目标值
    float fb_LSpeed;  // 闭环左速度
    float fb_RSpeed;  // 闭环右速度
    float fb_angle;   // 目标角度
    float fb_angleSpeed;  // 角度基础速度
    float fb_trackSpeed;  // 循迹基础速度
    // 输出值
    float out_LSpeed;      // 左速度
    float out_RSpeed;      // 右速度

    // 实际值
    float real_LSpeed; // 左速度
    float real_RSpeed; // 右速度
    float real_angle;  // 角度
    
    int _encL; // 上次编码器值
    int _encR; // 上次编码器值
    Tracker_t tracker; // 循迹板

    uint32_t tracker_event_cmp_time_line;
    uint32_t tracker_event_cmp_time_noline;
    uint32_t event;    // 触发检测
    CarPort_t *port;
    Car_ctrl_state_e state;
    Car_ctrl_task_e task;
    uint32_t taskTime;
    CarKeyPoint_t *keyPoint;
    uint16_t keyPointSize;
    uint32_t keyPointCnt;
    float startAngle;
    int delayTime;
}Car_ctrl_t;


/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/
extern Car_ctrl_t CarCtrl;
// 初始化，在所有任务开始之前调用
int car_ctrl_init(CarPort_t *port);

// 定向旋转直线运动
int car_ctrl_start_rotate(float angle, float speed);
// 循迹
int car_ctrl_start_track(float speed);
// 停车
int car_ctrl_stop(void);
// 任务循环
void car_ctrl_speed_loop(void);
void car_ctrl_angle_loop(void);
void car_ctrl_track_loop(void);
void car_ctrl_check_point(void);

// 功能函数
void car_ctrl_task_event(uint32_t events);
void car_ctrl_task1_start(const void * arg);
void car_ctrl_task2_start(const void * arg);
void car_ctrl_task_start(Car_ctrl_task_e taskID);
void car_ctrl_auto_start(CarKeyPoint_t *keyPoint, uint8_t keyPointSize);
void car_ctrl_do_keypoint(CarKeyPoint_t *keyPoint);
void car_ctrl_set_speed(float speedL, float speedR);
void car_ctrl_rotate_open(float time, float speed);

// 参数配置
void car_task2_config_C(uint16_t time, int8_t speed);
void car_task3_config_B(uint16_t time, int8_t speed);
void car_task4_config_AB(int8_t speedAll, uint16_t time1, int8_t speed1, uint16_t time2, int8_t speed2);
// 外部声明
#define TASK2_SIZE (6)
#define TASK3_SIZE (6)
#define TASK4_SIZE (6*4)
extern CarKeyPoint_t gtask2[TASK2_SIZE];
extern CarKeyPoint_t gtask3[TASK3_SIZE];
extern CarKeyPoint_t gtask4[TASK4_SIZE];

#ifdef __cplusplus
	}
#endif
#endif
